package com.xplay.xpocker.room.mahjong.settlement;

import com.xplay.xpocker.constant.ConstantDict;
import com.xplay.xpocker.constant.RoomTypeEnum;
import com.xplay.xpocker.dvo.AbstractRoom;
import com.xplay.xpocker.dvo.GameRuMahjongUserState;
import com.xplay.xpocker.entity.GameHiRoomDTO;
import com.xplay.xpocker.entity.GameRuMahjongLogs;
import com.xplay.xpocker.entity.GameRuMahjongOpenDeal;
import com.xplay.xpocker.room.mahjong.AbstractIsolationEventStrategy;
import com.xplay.xpocker.room.mahjong.constant.PbTypeEnum;
import com.xplay.xpocker.room.mahjong.dto.EFScoreInfo;
import com.xplay.xpocker.room.mahjong.dto.MahjongRoomInfo;
import com.xplay.xpocker.room.mahjong.dto.MahjongRoomRule;
import com.xplay.xpocker.room.mahjong.dto.ScoreInfo;
import com.xplay.xpocker.room.mahjong.util.MahjongHuUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
public class CdIsolationEvent extends AbstractIsolationEventStrategy {

    @Override
    protected RoomTypeEnum strategyName() {
        return RoomTypeEnum.CD_MAHJONG;
    }

    @Override
    public void settlementBar(GameRuMahjongUserState currentUser, GameRuMahjongUserState exportUser, Integer type, Integer card, AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {
        PbTypeEnum ofType = PbTypeEnum.ofType(type);
        if (ofType.equals(PbTypeEnum.MING_BAR) || ofType.equals(PbTypeEnum.DARK_BAR)) {
            // 点杠 和  暗杠
            int fraction = 2;
            if (ofType.equals(PbTypeEnum.MING_BAR)) {
                fraction = 1;
            }
            settlement(currentUser, exportUser, ofType.getName(), ofType.getName(), fraction, roomInfo, null);
        } else {
            settlement(currentUser, exportUser, ofType.getName(), ofType.getName(), 2, roomInfo, null);
        }

    }

    @Override
    public void settlementHu(GameRuMahjongUserState currentUser, GameRuMahjongUserState exportUser, Integer exportCard, AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {
        // 多少个杠  翻几番
        // 清一色    翻两番
        // 青大队    翻一番
        // 金钩钓    翻一番
        StringBuffer fractionInfo = new StringBuffer();
        // 成都麻将 算胡牌了哟
        List<Integer> handCards = currentUser.allHandCards();
        // 使用流进行深度拷贝
        List<Integer> copeHandCards = handCards.stream().map(Integer::new) // 使用拷贝构造器创建新的Integer对象
                .collect(Collectors.toList());

        // 判断是否为清一色
        if (exportCard != null) {
            copeHandCards.add(exportCard);
        }

        int multiple = 0, basisScore = 1, totalScore = 0, barCount = 0;
        //  带杠加番
        Map<Integer, Long> countMap = currentUser.allHandCards().stream().collect(Collectors.groupingBy(number -> number, Collectors.counting()));
        for (Map.Entry<Integer, Long> entry : countMap.entrySet()) {
            // 暗杠检测
            if (entry.getValue() > ConstantDict.Mahjong.HAND_THREE_COUNT) {
                barCount++;
            }
            // 明杠检测
            GameRuMahjongOpenDeal gameRuUserOpenDeal = currentUser.checkOpenDealBar(entry.getKey());
            if (gameRuUserOpenDeal != null) {
                barCount++;
            }
        }
        if (barCount > 0) {
            fractionInfo.append(barCount).append("个杠、");
        }
        // 清一色加两番
        int classCount = judgeUserCardClass(currentUser, exportCard);
        if (classCount == 1) {
            multiple += 2;
            fractionInfo.append("清一色、");
        }

        // 大队子加一番
        if (MahjongHuUtil.checkPokerAAA(copeHandCards, 0)) {
            multiple++;
            fractionInfo.append("大队子、");
        } else if (MahjongHuUtil.checkPokerAA(copeHandCards, 0)) {
            multiple++;
            fractionInfo.append("七对、");
        }

        //金勾勾 加一番
        if (handCards.size() == 2) {
            multiple++;
            fractionInfo.append("金勾勾、");
        }

        if (multiple == 0) {
            fractionInfo.append("小胡、");
        }
        multiple = multiple + barCount;
        totalScore = calculateScore(basisScore, multiple);


        fractionInfo.deleteCharAt(fractionInfo.length() - 1);
        // 自摸家底还是加番

        if (exportUser == null) {
            settlement(currentUser, null, String.format("自摸[%s]", fractionInfo), String.format("被自摸[%s]", fractionInfo), totalScore, roomInfo, null);
        } else {
            settlement(currentUser, exportUser, String.format("放炮[%s]", fractionInfo), String.format("点炮[%s]", fractionInfo), totalScore, roomInfo, null);
        }
    }

    @Override
    public void presentSettlement(AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo, GameHiRoomDTO gameHiRoomDTO) {

    }


    private int calculateScore(int baseScore, int multiplier) {
        int result = baseScore;
        for (int i = 0; i < multiplier; i++) {
            result *= 2;
        }
        return result;
    }


    @Override
    public ScoreInfo checkHu(GameRuMahjongUserState currentUser, GameRuMahjongUserState exportUser, Integer card, AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {
        // 成都麻将 算胡牌了哟
        List<Integer> handCards = currentUser.allHandCards();
        // 使用流进行深度拷贝
        List<Integer> copeHandCards = handCards.stream().map(Integer::new) // 使用拷贝构造器创建新的Integer对象
                .collect(Collectors.toList());

        // 判断是否为清一色
        if (card != null) {
            copeHandCards.add(card);
        }
        MahjongHuUtil.canHu(copeHandCards, 0, true);
        return null;
    }

    @Override
    public void checkUserAction(AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {

    }

    @Override
    public void gameStartActionCheck(AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {

    }

    @Override
    public boolean exportCardActionCheck(GameRuMahjongUserState current, Integer exportCard, AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {
        return false;
    }

    @Override
    public void dealCardActionCheck(GameRuMahjongUserState nextUser, Integer nextCard, AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {

    }

    @Override
    public List<EFScoreInfo> checkListenCards(GameRuMahjongUserState currentUser, AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {
        List<Integer> checkHInfo = MahjongHuUtil.checkHInfo(currentUser.allHandCards(), 0);

        return null;
    }

    @Override
    public List<MahjongHuUtil.CardEHInfo> checkExportListenCards(GameRuMahjongUserState currentUser) {
        return MahjongHuUtil.checkEHInfo(currentUser.allHandCards(), 0);
    }

    @Override
    public void bumpCardActionCheck(AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo, GameRuMahjongUserState current, GameRuMahjongUserState source, Integer cardCode) {

    }


}
